﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Award
{
    public class AwardSelection
    {
        private string[] saInitialPersonList = null;
        private List<string> lRemainingPersons = null;
        private List<string> lSelectingBuffer = new List<string>();
        private Tuple<int, string[], string>[] taSelectedPersons = null;
        private int iCurrentAwardLevel;
        public int CurrentAwardLevel
        {
            get { return this.iCurrentAwardLevel; }
        }

        private AwardMain wOwner;
        public AwardSelection(AwardMain Owner)
        {
            this.wOwner = Owner;
        }
        public void LoadPersonList()
        {
            string sListFilePath = Application.StartupPath + "\\PersonList.txt";
            if (System.IO.File.Exists(sListFilePath))
            {
                StreamReader sr = new StreamReader(sListFilePath);
                List<string> lLoadBuffer = new List<string>();
                while (!sr.EndOfStream)
                {
                    string sPerson = sr.ReadLine().Trim();
                    if (sPerson.Length > 0)
                    {
                        lLoadBuffer.Add(sPerson);
                    }
                }
                sr.Close();
                sr.Dispose();
                if (lLoadBuffer.Count == 0)
                {
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "人员文件列表格式不正确，请每行输入一个人名或编号。" });
                    }
                }
                else
                {
                    this.saInitialPersonList = lLoadBuffer.ToArray();
                    this.lRemainingPersons = lLoadBuffer;
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "成功导入了" + lLoadBuffer.Count.ToString() + "条人员记录。" });
                    }

                }
            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "没有找到人员列表文件，请将文件命名为“PersonList.txt”并放置于程序文件夹内！" });
                }

            }
        }
        public string[] RandomSelectPerson()
        {
            if (this.lRemainingPersons != null && this.taSelectedPersons != null
                && this.iCurrentAwardLevel < this.taSelectedPersons.Length)
            {
                this.lSelectingBuffer.Clear();
                int iCurrentLevelAwardSlotCount = this.taSelectedPersons[this.iCurrentAwardLevel].Item2
                    .Count(s => s == null);
                int iSelectablePersonCount = Math.Min(iCurrentLevelAwardSlotCount, this.lRemainingPersons.Count);
                Random r = new Random();
                for (int i = 0; i < Math.Min(this.taSelectedPersons[this.iCurrentAwardLevel].Item1,
                    iSelectablePersonCount); i++)
                {
                    string[] saSelectablePersons = this.lRemainingPersons.Except(this.lSelectingBuffer).ToArray();
                    this.lSelectingBuffer.Add(saSelectablePersons[r.Next(0, saSelectablePersons.Length)]);
                }
                return this.lSelectingBuffer.ToArray();
            }
            else
            {
                return null;
            }
        }
        public void ConfirmSelectedPersons()
        {
            if (this.iCurrentAwardLevel < this.taSelectedPersons.Length)
            {
                string[] saCurrentAwardSlots = this.taSelectedPersons[this.iCurrentAwardLevel].Item2;
                int iFilledCount = saCurrentAwardSlots.Count(s => s != null);
                if (this.lSelectingBuffer.Count == 0)
                {
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "目前没有抽取到的人员。" });
                    }

                    return;
                }
                if (iFilledCount + this.lSelectingBuffer.Count() <= saCurrentAwardSlots.Length)
                {
                    Array.Copy(lSelectingBuffer.ToArray(), 0, saCurrentAwardSlots,
                        iFilledCount, lSelectingBuffer.Count);
                    this.lRemainingPersons = this.lRemainingPersons.Except(this.lSelectingBuffer).ToList();
                    if (iFilledCount + this.lSelectingBuffer.Count() >= saCurrentAwardSlots.Length)
                    {
                        lock (this.wOwner)
                        {
                            this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "“" + this.taSelectedPersons[this.iCurrentAwardLevel].Item3
                            + "”已经抽完，共计抽出" + saCurrentAwardSlots.Length.ToString() + "个中奖者。" });
                        }

                        this.iCurrentAwardLevel++;
                        if (this.iCurrentAwardLevel >= this.taSelectedPersons.Length)
                        {
                            lock (this.wOwner)
                            {
                                this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "所有奖项已经抽完！" });
                            }

                        }
                    }
                }
                else
                {
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "当前抽奖情况与历史记录不匹配，请重新初始化再试。" });
                    }

                }
            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "当前抽奖情况与历史记录不匹配，请重新初始化再试。" });
                }

            }
        }
        public void ClearCurrentAwardLevel()
        {
            if (this.taSelectedPersons.Count() > this.iCurrentAwardLevel + 1)
            {
                this.lRemainingPersons.AddRange(this.taSelectedPersons[this.iCurrentAwardLevel].Item2);
                this.taSelectedPersons[this.iCurrentAwardLevel] = new Tuple<int, string[], string>(
                    this.taSelectedPersons[this.iCurrentAwardLevel].Item1,
                    new string[this.taSelectedPersons[this.iCurrentAwardLevel].Item2.Length],
                    this.taSelectedPersons[this.iCurrentAwardLevel].Item3);
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "成功清除了当前第" + (this.iCurrentAwardLevel + 1).ToString() + "波抽奖的结果。" });
                }

            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "清除当前波次抽奖结果失败，可能是由于相关数据未初始化所致，建议重新加载抽奖数据再试。" });
                }

            }
        }
        public void InitiallizeAwardLevel()
        {
            string sListFilePath = Application.StartupPath + "\\AwardLevel.txt";
            if (System.IO.File.Exists(sListFilePath))
            {
                StreamReader sr = new StreamReader(sListFilePath);
                List<Tuple<int, string[], string>> lALBuffer = new List<Tuple<int, string[], string>>();
                while (!sr.EndOfStream)
                {
                    string[] saAwardSetting = sr.ReadLine().Trim().Split(new char[] { ',' });
                    if (saAwardSetting.Length == 3)
                    {
                        int iTotalLimit;
                        if (!int.TryParse(saAwardSetting[0].Trim(), out iTotalLimit))
                        {
                            continue;
                        }
                        int iPerTimeLimit;
                        if (!int.TryParse(saAwardSetting[1].Trim(), out iPerTimeLimit))
                        {
                            continue;
                        }
                        Tuple<int, string[], string> tAwardSetting =
                            new Tuple<int, string[], string>(
                                iPerTimeLimit, new string[iTotalLimit], saAwardSetting[2].Trim());
                        lALBuffer.Add(tAwardSetting);
                    }
                }
                if (lALBuffer.Count == 0)
                {
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "奖项设置文件格式不正确，请在每行写入两个数字与一个奖项名称并用“，”分隔，"
                           +"前一个数字代表奖项容纳总人数，后一个数字代表每次抽奖结果人数。" });
                    }

                }
                else
                {
                    this.taSelectedPersons = lALBuffer.ToArray();
                    lock (this.wOwner)
                    {
                        this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "奖项设置初始化完成，总共导入" + lALBuffer.Count.ToString() + "条奖项设置。" });
                    }

                    lALBuffer.Clear();
                    this.iCurrentAwardLevel = 0;
                }
            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "没有找到奖项设置文件，请将文件名为“AwardLevel.txt”并放置于程序文件夹内！" });
                }

            }
        }
        public Tuple<string, string>[] GetCurrentSelectedPersons()
        {
            if (this.taSelectedPersons != null)
            {
                return this.taSelectedPersons.Reverse().Select(t => new Tuple<string, string>(
                    t.Item3, t.Item2.Aggregate((n1, n2) => n1 + " " + n2))).ToArray();
            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[] { "奖项初始化未完成，请重新初始化。" });
                }

                return null;
            }
        }
        public string GetCurrentStatistics()
        {
            StringBuilder sb = new StringBuilder();
            if (this.iCurrentAwardLevel >= this.taSelectedPersons.Length)
            {
                sb.AppendLine("当前奖项：没有更多奖项了");
            }
            else
            {
                sb.AppendLine("当前奖项：" + this.taSelectedPersons[this.iCurrentAwardLevel].Item3);
            }
            sb.AppendLine("当前抽奖结果：");
            if (this.taSelectedPersons != null)
            {
                foreach (var item in this.taSelectedPersons.Reverse())
                {
                    sb.AppendLine(string.Format("{0}:\r\n 奖品总数{1}\r\n 已抽出{2}\r\n", item.Item3, item.Item2.Length,
                        item.Item2.Count(s => s != null)));
                }
            }
            else
            {
                lock (this.wOwner)
                {
                    this.wOwner.Invoke(this.wOwner.dShowMessageBox, new object[]{"奖项尚未初始化，请初始化后再抽奖。"});
                }
            }
            return sb.ToString();
        }
    }
}
